package fileLoader;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.NameValuePair;

/**
 *
 * class ServerConnector which is responsible for contacting the server
 *
 */
public class ServerConnector {

	public static String username;
	public static String ip;
	/**
	 * 
	 * @param file_path
	 * @param f
	 * @return true if server doesn't already contain file with same hash as f,
	 * false otherwise
	 */
	public static boolean checkHash(String file_path,File f)
	{			
		try {
			//getting file name
			String file_name=f.getName();
			//getting name of folder which includes f
			String folder_name=f.getParent();

			//calculating the hash of the file
			FileReader fl=new FileReader(f);
			byte[] b = null;
			FileInputStream fileInputStream = new FileInputStream(f);
			b = new byte[(int) f.length()];
			fileInputStream.read(b);
			fileInputStream.close();
			MessageDigest m;
			m = MessageDigest.getInstance("MD5");
			m.update(b,0,b.length);
			//getting the hash
			String hash=new BigInteger(1,m.digest()).toString(16);


			//contacting the server
			HttpClient httpclient = new DefaultHttpClient();
			httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
			HttpPost request = new HttpPost("http://"+ip+":8080/ProjServer/check_hash");
			List<NameValuePair> postParameters = new ArrayList<NameValuePair>(); 
		
			//adding parameters which will be sent to servlet
			NameValuePair x=new BasicNameValuePair("hash", hash);
			NameValuePair y=new BasicNameValuePair("folder", folder_name);
			NameValuePair z=new BasicNameValuePair("fileName", file_name);
			//adding them to postParameters
			postParameters.add(x);
			postParameters.add(y);
			postParameters.add(z);
			postParameters.add(new BasicNameValuePair("user",username));
			UrlEncodedFormEntity formEntity;

			formEntity = new UrlEncodedFormEntity((List<? extends org.apache.http.NameValuePair>) postParameters);
			request.setEntity(formEntity);
			//sending request
			HttpResponse response = httpclient.execute(request);

			BufferedReader rd = new BufferedReader(new InputStreamReader( response.getEntity().getContent()));
			//reading the server's response
			String line = rd.readLine();
			rd.close();
			fl.close();
			httpclient.getConnectionManager().shutdown();
			if(line.equals("true"))
				return true;
			else
				return false;



		} 
		catch (Exception e) {
			// TODO Auto-generated catch block
		
		}
		
		return false;
		
	}
	
	/**
	 * 
	 * @param file_path
	 * uploads file to server (if server doesn't have file with same hash)
	 */
	public static void postFile(String file_path)	
	{
		
		
		HttpClient httpclient = new DefaultHttpClient();
		httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

		HttpPost httppost = new HttpPost("http://"+ip+":8080/ProjServer/upload");
		File file = new File(file_path);

		//if server doesn't have the file yet
		if(checkHash(file_path, file))
		{
			MultipartEntity mpEntity = new MultipartEntity();
			ContentBody cbFile = new FileBody(file);
			mpEntity.addPart("userfile", cbFile);
			httppost.setEntity(mpEntity);
			
			HttpResponse response;
			try {
				//uploading file
				response = httpclient.execute(httppost);
				HttpEntity resEntity = response.getEntity();

				if (resEntity != null) {

					resEntity.consumeContent();
				}
				
				httpclient.getConnectionManager().shutdown();

			}
			catch(Exception e)
			{

			}
		}
	}
	
	/**
	 * 
	 * @param folder_name
	 * @param username
	 * goes to registerServlet
	 */
	public static void registerFolderInServer(String folder_name,String username) 
	{

		HttpClient httpclient = new DefaultHttpClient();
		httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

		//request ro registerFolderServlet
		HttpPost request = new HttpPost("http://"+ip+":8080/ProjServer/register");


		List<NameValuePair> postParameters = new ArrayList<NameValuePair>(); 
		
		//sending username and foldername
		NameValuePair d=new BasicNameValuePair("username", username);
		postParameters.add(d);
		postParameters.add(new BasicNameValuePair("foldername", folder_name));
		UrlEncodedFormEntity formEntity;
		try {
			formEntity = new UrlEncodedFormEntity((List<? extends org.apache.http.NameValuePair>) postParameters);
			request.setEntity(formEntity);
			//sending request to the servlet
			HttpResponse response = httpclient.execute(request);

			httpclient.getConnectionManager().shutdown();

		} catch (Exception e) 
		{
			// TODO Auto-generated catch block
		
		}

	}
	
	/**
	 * 
	 * @param file_id
	 * @param new_file_name
	 * @param folder_name
	 * downloads file with given file_id from server
	 */
	public static void downloadFileFromServer(String file_id,String new_file_name, String folder_name) 
	{
		try{
			System.out.println("download file from server "+file_id+" "+new_file_name+" "+" "+folder_name);


			if(folder_name.contains("C:\\dropbox")){
				folder_name = folder_name.substring(folder_name.lastIndexOf("\\")+1);
			}	

			HttpClient httpclient1 = new DefaultHttpClient();
			httpclient1.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
			
			//sending request to DownloadServlet
			HttpPost request1 = new HttpPost("http://"+ip+":8080/ProjServer/download");
			List<NameValuePair> postParameters1 = new ArrayList<NameValuePair>(); 
			
			//sending the file id we want to download
			postParameters1.add(new BasicNameValuePair("file_id",file_id.toString()));
			UrlEncodedFormEntity formEntity1;
			formEntity1 = new UrlEncodedFormEntity((List<? extends org.apache.http.NameValuePair>) postParameters1);
			request1.setEntity(formEntity1);

			//sending request to servlet
			HttpResponse response1 = httpclient1.execute(request1);
			InputStream in=response1.getEntity().getContent();

			File f=new File("C:\\dropbox\\"+folder_name+"\\"+new_file_name);

			
			//writing to file
			FileOutputStream fos = new FileOutputStream(f);
			byte[] buffer = new byte[1024];
			int len = in.read(buffer);
			while (len != -1)
			{     
				fos.write(buffer, 0, len);
				len = in.read(buffer); 
			} 
	
			fos.flush();
			fos.close();
			httpclient1.getConnectionManager().shutdown();

			//adding tags to the new file
			String[] labels=new Test().dynamicLoadAndLabel("C:\\dropbox\\"+folder_name+"\\"+new_file_name);
			DBTagsMgr.addTags("C:\\dropbox\\"+folder_name+"\\"+new_file_name,labels);


		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * @param filePath
	 * goes to deleteFileServlet
	 */
	public static void deleteFileFromServer(String filePath ){
		
		try{

			System.out.println("in server connector deleting file");
			
			HttpClient httpclient = new DefaultHttpClient();
			httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
			HttpPost request = new HttpPost("http://"+ip+":8080/ProjServer/delete_file");

			System.out.println("filepath:"+filePath);

			List<NameValuePair> postParameters = new ArrayList<NameValuePair>(); 

			String[] elems=filePath.split("\\\\");
			String folder_name=elems[elems.length-2];
			
			System.out.println("folder name "+folder_name);

			//sending folder name, username and file name
			postParameters.add(new BasicNameValuePair("username",ServerConnector.username));
			postParameters.add(new BasicNameValuePair("folder_name",folder_name));
			postParameters.add(new BasicNameValuePair("filename",elems[elems.length-1]));

			UrlEncodedFormEntity formEntity;

			formEntity = new UrlEncodedFormEntity((List<? extends org.apache.http.NameValuePair>) postParameters);
			request.setEntity(formEntity);

			//sending request to deleteFileServlet
			HttpResponse response = httpclient.execute(request);
			
			httpclient.getConnectionManager().shutdown();

		}
			catch(Exception e)
			{
				
			}
	}
	
	/**
	 * 
	 * @param fPath
	 * goes to deleteFolderServlet
	 */
	public static void deleteFolderFromServer(String fPath ){
		
		try{
			HttpClient httpclient = new DefaultHttpClient();
			httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
			HttpPost request = new HttpPost("http://"+ip+":8080/ProjServer/delete_folder");

			List<NameValuePair> postParameters = new ArrayList<NameValuePair>(); 

			//getting folder_name
			String[] elems=fPath.split("/");
			String folder_name=elems[elems.length-1];

			//adding parameters user name and folder name
			postParameters.add(new BasicNameValuePair("username",ServerConnector.username));
			postParameters.add(new BasicNameValuePair("folder_name",folder_name));


			UrlEncodedFormEntity formEntity;

			formEntity = new UrlEncodedFormEntity((List<? extends org.apache.http.NameValuePair>) postParameters);
			request.setEntity(formEntity);
			//sending request to deleteFolderServlet
			HttpResponse response = httpclient.execute(request);

		}
		catch(Exception e)
		{

		}
	}
}
